﻿using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;

namespace ipi.MCC.Global
{
    public partial class Exceptions
    {
        private const int iPadException = 2;
        private const int iPadNamespace = 2;
        private const int iPadClass = 3;
        private const int iPadMethod = 4;
        
        public static string HandleException(Exception exc, Type CurrentType, MethodBase Method, LoggingType ltCurrent)
        {
            string sResult;

            string sErrorNumber = Exceptions.GetErrorNumber(exc, CurrentType.Namespace, CurrentType.Name, Method.Name);
            string sErrorText = string.Empty;
            string sExceptionName = exc.GetType().Name;

            if (exc is NullReferenceException)
            {
                sErrorText = GetGeneralException();
            }
            else if (exc is IndexOutOfRangeException)
            {
                sErrorText = GetGeneralException();
            }
            else
            {
                sErrorText = exc.Message;
            }

            Functions.WriteEventLog(Exceptions.GetMethodPath(CurrentType, Method), sExceptionName, sErrorNumber, sErrorText);
            
            if((exc is TreeListAccessDeniedException) || (exc is UserHandlingException))
            {
                sResult = sErrorText;
            }
            else
            {
                sResult = Resources.Resources.Exceptions_Prefix + " " + sErrorNumber + ": " + sErrorText;
            }

            return sResult;
        }

        public static string GetMethodPath(Type CurrentType, MethodBase Method)
        {
            return CurrentType.Namespace + "." + CurrentType.Name + "." + Method.Name;
        }

        protected static string GetErrorNumber(Exception exc, string NameSpace, string ClassName, string MethodName)
        {
            return GetExceptionNumber(exc).ToString().PadLeft(iPadException, '0') +
                                  GetNamespaceNumber(NameSpace).ToString().PadLeft(iPadNamespace, '0') +
                                  GetClassNumber(ClassName).ToString().PadLeft(iPadClass, '0') +
                                  GetMethodNumber(MethodName).ToString().PadLeft(iPadMethod, '0');
        }

        public static void DecodeErrorNumber(string ErrorNumber, out string MethodPath, out string ExceptionName)
        {
            try
            {
                int iExceptionNumber = Convert.ToInt32(ErrorNumber.Substring(0, iPadException));
                int iNamespaceNumber = Convert.ToInt32(ErrorNumber.Substring(iPadException - 1, iPadNamespace));
                int iClassNumber = Convert.ToInt32(ErrorNumber.Substring(iPadException + iPadNamespace - 1, iPadClass));
                int iMethodNumber = Convert.ToInt32(ErrorNumber.Substring(iPadException + iPadNamespace + iPadClass - 1, iPadMethod));

                ExceptionName = GetExceptionName(iExceptionNumber);
                MethodPath = GetNamespaceName(iNamespaceNumber) + "." + GetClassName(iClassNumber) + "." + GetMethodName(iMethodNumber);
            }
            catch (Exception)
            {
                MethodPath = string.Empty;
                ExceptionName = string.Empty;
            }
        }

        private static string GetGeneralException()
        {
            return Resources.Resources.Exceptions_GeneralException;
        }       
    }

    public class TreeListAccessDeniedException : Exception
    {
        public TreeListAccessDeniedException()
            : base(Resources.Resources.GetTreeList_AccessDenied)
        {
        }
    }

    public class UserHandlingException : Exception
    {
        public UserHandlingException(string Message)
            : base(Message)
        {
        }
    }
}
